﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;

namespace TCG
{
    /// <summary>
    /// 工具类，材质的序列化和反序列化。
    /// </summary>
    public static class MaterialSerializer
    {
        /// <summary>
        /// 将材质序列化到protobuf流中，而后写入序列化目标文件。
        /// </summary>
        public static void Serialize (Material mat)
        {
			string targetPath = GameEditorTools.GetPathForSerilize (mat);
			if (string.IsNullOrEmpty (targetPath))
			{
				throw new System.Exception (string.Format ("材质{0}应该位于{1}文件夹或其子文件夹中", mat.name, GameEditorTools.SerializableSourceDir));
			}

			// 检查材质命名
			CommonTools.ParseAssetIdFromName (mat.name);


            // 构建MaterialData类
            MaterialData data = new MaterialData ();

            IList<ColorInMat> colors = new List<ColorInMat> ();
            IList<FloatInMat> floats = new List<FloatInMat> ();
            IList<TextureInMat> textures = new List<TextureInMat> ();
            IList<VectorInMat> vectors = new List<VectorInMat> ();

            int shaderProps = ShaderUtil.GetPropertyCount (mat.shader);
            for (int i = 0; i < shaderProps; ++ i)
            {
                ShaderUtil.ShaderPropertyType propType = ShaderUtil.GetPropertyType (mat.shader, i);
                string propName = ShaderUtil.GetPropertyName (mat.shader, i);
                switch (propType)
                {
                    case ShaderUtil.ShaderPropertyType.Color: 
                        colors.Add (new ColorInMat (propName, mat.GetColor (propName)));
                        break;

                    case ShaderUtil.ShaderPropertyType.Float: 
                        floats.Add (new FloatInMat (propName, mat.GetFloat (propName)));
                        break;

                    case ShaderUtil.ShaderPropertyType.Range: 
                        floats.Add (new FloatInMat (propName, mat.GetFloat (propName)));
                        break;

                    case ShaderUtil.ShaderPropertyType.TexEnv: 
						Texture tex = mat.GetTexture (propName);
						if (tex == null)
						{
							throw new System.Exception ("材质关联的贴图丢失：" + mat.name);
						}
                        textures.Add (new TextureInMat (propName, mat.GetTexture (propName).name, 
                            mat.GetTextureOffset (propName), 
                            mat.GetTextureScale (propName)));
                        break;

                    case ShaderUtil.ShaderPropertyType.Vector: 
                        vectors.Add (new VectorInMat (propName, mat.GetVector (propName)));
                        break;
                }
            }
            data.shaderName = mat.shader.name;
            data.colors = colors;
            data.floats = floats;
            data.textures = textures;
            data.vectors = vectors;
			data.matName = mat.name + "_rt";

            // 写入文件中
			System.IO.Stream fileStream = new System.IO.FileStream (targetPath, System.IO.FileMode.Create);
            data.Serialize (fileStream);
			fileStream.Close ();
			AssetDatabase.Refresh ();
        }
	}
}
